﻿//Complex number class
namespace Diplom.NumericArrays
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    public class Complex{
        #region Fields
        double real, image;
        double EPS = 1e-9;
        #endregion

        #region Constructor

        /// <summary>
        /// Default constructor
        /// </summary>
        public Complex()
        {
            real = 0;
            image = 0;
        }

        /// <summary>
        /// Real Constructor
        /// </summary>        
        public Complex(double real):this()
        {
            this.real = real;           
        }

        /// <summary>
        /// Complex Constructor
        /// </summary>        
        public Complex(double real, double image)
            : this()
        {
            this.real = real;
            this.image = image;
        }

        #endregion

        #region Properties
        /// <summary>
        /// Real part of number
        /// </summary>
        public Double Real
        {
            get
            {
                return this.real;
            }
        }

        /// <summary>
        /// Image part of number
        /// </summary>
        public Double Image
        {
            get
            {
                return this.image;
            }
        }

        #endregion

        #region Methods

        /// <summary>
        /// Pairing of Number
        /// </summary>        
        public static Complex Pair(Complex a)
        {
            return new Complex(a.Real, -a.Image);
        }

        /// <summary>
        /// Summ of complex numbers
        /// </summary>        
        public static Complex operator+ (Complex a, Complex b)
        {
            return new Complex(a.Real + b.Real, a.Image + b.Image);
        }

        /// <summary>
        /// Diff of cumplex numbers
        /// </summary>        
        public static Complex operator -(Complex a, Complex b)
        {
            return new Complex(a.Real - b.Real, a.Image - b.Image);
        }

        /// <summary>
        /// Mult of cumplex numbers
        /// </summary>        
        public static Complex operator *(Complex a, Complex b)
        {
            return new Complex(a.Real * b.Real - a.Image * b.Image, a.Real * b.Image + a.Image * b.Real);
        }

        /// <summary>
        /// Div of complex numbers
        /// </summary>        
        public static Complex operator /(Complex a, Complex b)
        {
            Complex tmp = a * Pair(b);
            double divide = b.Real * b.Real + b.Image * b.Image;
            tmp.real /= divide;
            tmp.image /= divide;
            return tmp;
        }

        /// <summary>
        /// Norma of numbers
        /// </summary>        
        public double Norma()
        {
            return Math.Sqrt(this.real * this.real + this.image * this.image);
        }

        /// <summary>
        /// Compare of numbers
        /// </summary>
        public static bool operator ==(Complex a,Complex b){
            return a.Equals(b);
        }


        /// <summary>
        /// Compare of numbers
        /// </summary>
        public static bool operator !=(Complex a, Complex b)
        {
            return !a.Equals(b);
        }

        /// <summary>
        /// Override Equals Operator
        /// </summary>        
        public override bool  Equals(object obj)
        {
            Complex b=obj as Complex;
            if (b==null) return false;
 	        if (Math.Abs(this.real - b.real)>EPS) return false;
            if (Math.Abs(this.image - b.image)>EPS) return false;
            return true;
        }

        /// <summary>
        /// Override ToString operator
        /// </summary>
        /// <returns></returns>
        public override string  ToString()
        {
            if (Math.Abs(this.image)>EPS){
 	            return this.real.ToString("F5")+" + i * "+this.image.ToString("F5");
            }else{
                return this.real.ToString("F5");
            }
        }

        /// <summary>
        /// Override GetHashCode
        /// </summary>        
        public override int GetHashCode()
        {
            return ((int)this.real*10000).GetHashCode() + ((int)this.image*10000).GetHashCode();
        }

        #endregion
    }
}
